package org.example.shardUpload;


import org.example.nettyrpc.EndpointBase;
import org.example.nettyrpc.common.IpPortTuple;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import static org.example.shardUpload.common.UploadProperties.File_Shard_SIZE;

public class UploadServer extends EndpointBase {

    public UploadServer(IpPortTuple myIpPort) {
        super(myIpPort, new IpPortTuple[]{});
    }

    public boolean requestUpLoadShard(String fileName, Integer shardIndex, Integer shardLen, byte[] data, String fileMd5) throws IOException {
        String[] nameItems = fileName.split("/");
        String saveDirname = "./src/main/java/org/example/shardUpload/tempShards/" + nameItems[nameItems.length - 1];
        File dir = new File(saveDirname);
        if (dir.exists() || dir.mkdir()) {
            String saveShardName = saveDirname + "/shard-" + fileMd5 + "-" + shardIndex;
            FileOutputStream fileOutputStream = new FileOutputStream(saveShardName);
            fileOutputStream.write(data, 0, shardLen);
            fileOutputStream.close();
        } else {
            return false;
        }

        return true;
    }

    public boolean requestMergeShards(String filename, Integer ShardNum, String md5checksum) throws IOException {
        String[] nameItems = filename.split("/");
        String dirname = "./src/main/java/org/example/shardUpload/tempShards/" + nameItems[nameItems.length - 1];

        File dir = new File(dirname);
        File[] files = dir.listFiles();

        if (files.length != ShardNum) {
            return false;
        }

        String saveFilename = "./src/main/java/org/example/shardUpload/server-" + nameItems[nameItems.length - 1];
        FileOutputStream fileOutput = new FileOutputStream(saveFilename, true);

        byte[] buf = new byte[File_Shard_SIZE];
        for (File file : files) {
            String[] items = file.getName().split("-");
            if (!md5checksum.equals(items[1])) {
                fileOutput.close();
                return false;
            }

            FileInputStream shardInput = new FileInputStream(file);
            int shardLen = shardInput.read(buf, 0, File_Shard_SIZE);
            fileOutput.write(buf, 0, shardLen);
            shardInput.close();
        }

        fileOutput.close();

        return true;
    }

    public ArrayList<Integer> searchSentSuccessShard(String filename, String md5checksum) {
        String[] nameItems = filename.split("/");
        String dirname = "./src/main/java/org/example/shardUpload/tempShards/" + nameItems[nameItems.length - 1];

        File dir = new File(dirname);
        File[] files = dir.listFiles();
        ArrayList<Integer> sent = new ArrayList<>();
        if (files != null) {
            for (File file : files) {
                String[] items = file.getName().split("-");
                if (md5checksum.equals(items[1])) {
                    sent.add(Integer.valueOf(String.valueOf(items[2])));
                }
            }
        }

        return sent;
    }
}
